import axios from "axios";

import { message } from "ant-design-vue";
import useGlobalStore from "@/stores/global.store";
import dayjs from "dayjs";
import signature from "@/utils/signature";
// import signature from "@ms/components/src/utils/signature";

let token =
    "eyJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJtZWRpYXJlc291cmNlbGliLWF1dGgiLCJhdWQiOiIyIiwiZXhwIjoxNzE0MzgzNzgwLCJpYXQiOjE3MTM3Nzg5ODAsInVzZXJJZCI6IjIifQ.Ak2OGHtLVUFbXY-3E5qwrkSz6SdRaAB9z8nPt9XPjofDOU8Kp4mcquJaQYdYMQpdauxFcgDUuB2wisjKmBBKv9wHhcdCmdjc2jM492OfemYyb2LFL56OyO-S5QeXMHlSeB9xJaxJQaU8sYL1dUNdd5UPhn5KHDj_QhKDCVHuYC80WePASqmipr7JnFAR9rTIHfuT0mU93QIqvtpC6sCQ81r0V-K-oZ79-9jHnhj1GL2tE2NCc11BsunYCGIzE9q6zOW-YrwTi7ALS4gS9TD8wPg2I_jPra2EWDRxd_0FiPNffWvP-_G60eHUbvDI3kJarErEoQFpivr_M7yQm6XZbg";

const service = axios.create({
    baseURL: "/",
    timeout: 60000,
});

export const CancelToken = axios.CancelToken;

async function updateToken(expires_in: number, token: string) {
    let end = dayjs(Number(expires_in));
    let start = dayjs();
    let offset = end.diff(start, "h");

    if (offset < 2) {
        let prefix = "";
        prefix = import.meta.env.VITE_APP_FREFIX || "";
        let res = await service.post<
            Response<{ access_token: string; expires_in: string }>
        >(`${prefix}/usersys-app/access-token/refresh`, {
            old_access_token: token,
        });
        let data = res.data.result.data;
        if (data) {
            localStorage.setItem("token", data.access_token);
            localStorage.setItem("expires_in", data.expires_in);

            return data.access_token;
        }
        return token;
    }
    return token;
}

const appKey = import.meta.env.VITE_APP_SIGN_KEY;
const appSecret = import.meta.env.VITE_APP_SIGN_SECRET;

service.interceptors.request.use(async (req) => {
    let url = req.url;

    if (localStorage.getItem("token")) {
        req["headers"]["Authorization"] =
            `Bearer ` + localStorage.getItem("token");
    } else {
        req["headers"]["Authorization"] = `Bearer ` + token;
    }

    req["headers"]["BZ-HEADER-DEVICE"] = "pc";

    let signObj = signature(appKey, appSecret, req);
    Object.assign(req["headers"], signObj);

    let prefix = "";
    // prefix = process.env.VUE_APP_PREFIX || "";

    if (url?.includes("https://") || url?.includes("http://")) {
    } else {
        req.url = prefix + url;
    }

    return req;
});

// ts 节流函数
function throttle(fn: (...rest: any[]) => void, delay = 5000) {
    let timer: any;
    return function (this: any, ...args: any[]) {
        if (!timer) {
            fn.apply(this, args);
            timer = setTimeout(() => {
                clearTimeout(timer);
                timer = null;
            }, delay);
        }
    };
}
let msgErrorFn = throttle(message.error);
service.interceptors.response.use(
    (res) => {
        // console.log(res.data);
        if (res.status == 200) {
            if (res.data instanceof Blob) {
                return res;
            } else {
                if (res.data.status_code == 1) {
                    // 请求成功
                } else {
                    if (res.data.msg) {
                        message.error(res.data.msg);
                    }
                    return Promise.reject(res);
                }
            }
        }

        return res;
    },
    (err) => {
        if (err.code !== "ERR_CANCELED") {
            if (err.response.status != 404 && err.response.status != 401) {
                message.error(err.response?.data?.msg || err.message);
            }
            if (err.response.status == 401) {
                const { logOut } = useGlobalStore();
                logOut();
            }
        }
        return Promise.reject(err);
    },
);

export default service;

export interface Pagination {
    current_page: number;
    total_count: number;
    total_pages: number;
    page_items: number;
    last_id: string;
}
export interface Response<T = any> {
    status_code: number;
    msg: string;
    result: {
        data: T;
        page: {} | Pagination;
    };
}

export function authGuard(
    target: any,
    name: string,
    descriptor: PropertyDescriptor,
) {
    let fnStr = descriptor.value.toString() as string;
    let method = "";
    let api = "";
    // fnStr =
    //     "return n.ZP.put(`/usersys-auth/user/state?userId=${e}&state=${t}`)";
    let s = fnStr.replace(
        /return.*\.(.*?)\([`'"](.*?)[`'"][,)]/g,
        (match, p1, p2, offset, str) => {
            method = p1.toLocaleUpperCase();
            api = p2;
            return str;
        },
    );
    api = api.replace(/\?.*/g, "");
    api = api.replace(/\$\{.*\}/g, "?");
    // console.log(method, api);
    target[name.toLocaleUpperCase()] = `${method}-${api}`;
}
